Offline mode

  • An API client that adds offline features on top of the regular online API client.

    Note

    Requires Algolia’s Offline Core SDK. The enableOfflineMode(...) method must be called with a valid license key prior to calling any offline-related method.
    See more

    Declaration

    Swift

    @objcMembers
    public class OfflineClient : Client
  • An online index that can also be mirrored locally.

    Note

    You cannot construct this class directly. Please use OfflineClient.index(withName:) to obtain an instance.

    Note

    Requires Algolia Offline Core. The OfflineClient.enableOfflineMode(...) method must be called with a valid license key prior to calling any offline-related method.

    When created, an instance of this class has its mirrored flag set to false, and behaves like a normal, online Index. When the mirrored flag is set to true, the index becomes capable of acting upon local data.

    Warning

    It is a programming error to call methods acting on the local data when mirrored is false. Doing so will result in an assertion error being raised.

    Request strategy

    When the index is mirrored and the device is online, it becomes possible to transparently switch between online and offline requests. There is no single best strategy for that, because it depends on the use case and the current network conditions. You can choose the strategy through the requestStrategy property. The default is FallbackOnFailure, which will always target the online API first, then fallback to the offline mirror in case of failure (including network unavailability).

    Note

    If you want to explicitly target either the online API or the offline mirror, doing so is always possible using searchOnline(...) or searchOffline(...).

    Note

    The strategy applies to:

    • search(...)
    • searchDisjunctiveFaceting(...)
    • multipleQueries(...)
    • getObject(...)
    • getObjects(...)

    Bootstrapping

    Before the first sync has successfully completed, a mirrored index is not available offline, because it has simply no data to search in yet. In most cases, this is not a problem: the app will sync as soon as instructed, so unless the device is offline when the app is started for the first time, or unless search is required right after the first launch, the user should not notice anything.

    However, in some cases, you might need to have offline data available as soon as possible. To achieve that, MirroredIndex provides a manual build feature.

    Manual build

    Manual building consists in specifying the source data for your index from local files, instead of downloading it from the API. Namely, you need:

    • the index settings (one JSON file); and
    • the objects (as many JSON files as needed, each containing an array of objects).

    Those files are typically embedded in the application as resources, although any other origin works too.

    Conditional bootstrapping

    To avoid replacing the local mirror every time the app is started (and potentially overwriting more recent data synced from the API), you should test whether the index already has offline data using the hasOfflineData property.

    Discussion

    Warning

    We strongly advise against prepackaging index files. While it may work in some cases, Algolia Offline makes no guarantee whatsoever that the index file format will remain backward-compatible forever, nor that it is independent of the hardware architecture (e.g. 32 bits vs 64 bits, or Little Endian vs Big Endian). Instead, always use the manual build feature.

    While a manual build involves computing the offline index on the device, and therefore incurs a small delay before the mirror is actually usable, using plain JSON offers several advantages compared to prepackaging the index file itself:

    • You only need to ship the raw object data, which is smaller than shipping an entire index file, which contains both the raw data and indexing metadata.

    • Plain JSON compresses well with standard compression techniques like GZip, whereas an index file uses a binary format which doesn’t compress very efficiently.

    • Build automation is facilitated: you can easily extract the required data from your back-end, whereas building an index would involve running the app on each mobile platform as part of your build process and capturing the filesystem.

    Also, the build process is purposedly single-threaded across all indices, which means that on most modern devices with multi-core CPUs, the impact of manual building on the app’s performance will be very moderate, especially regarding UI responsiveness.

    Limitations

    Algolia’s core features are fully supported offline, including (but not limited to): ranking, typo tolerance, filtering, faceting, highlighting/snippeting

    However, and partly due to tight memory, CPU and disk space constraints, some features are disabled:

    • Synonyms are only partially supported:

      • Multi-way (regular) synonyms are fully supported.
      • One-way synonyms are not supported.
      • Alternative corrections are limited to one alternative (compared to multiple alternatives with online indices).
      • Placeholders are fully supported.
    • Dictionary-based plurals are not supported. (Simple plurals with a final S are supported.)

    • IP geolocation (see Query.aroundLatLngViaIP) is not supported.

    • CJK segmentation is not supported.

    Resource handling

    Native resources are lazily instantiated when mirrored is set to true. They are released when the object is released, or if mirrored is set to false again.

    See more

    Declaration

    Swift

    @objcMembers
    public class MirroredIndex : Index
  • A data selection query, used to select data to be mirrored locally by a MirroredIndex.

    See more

    Declaration

    Swift

    @objcMembers
    public class DataSelectionQuery : NSObject
  • A purely offline index. Such an index has no online counterpart. It is updated and queried locally.

    Note

    You cannot construct this class directly. Please use OfflineClient.offlineIndex(withName:) to obtain an instance.

    Note

    Requires Algolia Offline Core. OfflineClient.enableOfflineMode(...) must be called with a valid license key prior to calling any offline-related method.

    Reading

    Read operations behave identically as with online indices.

    Writing

    Updating an index involves rebuilding it, which is an expensive and potentially lengthy operation. Therefore, all updates must be wrapped inside a transaction.

    The procedure to update an index is as follows:

    • Create a transaction by calling newTransaction().

    • Populate the transaction: call the various write methods on the WriteTransaction class.

    • Either commit() or rollback() the transaction.

    Synchronous vs asynchronous updates

    Any write operation, especially (but not limited to) the final commit, is potentially lengthy. This is why all operations provide an asynchronous version, which accepts an optional completion handler that will be notified of the operation’s completion (either successful or erroneous).

    If you already have a background thread/queue performing data-handling tasks, you may find it more convenient to use the synchronous versions of the write methods. They are named after the asynchronous versions, suffixed by Sync. The flow is identical to the asynchronous version (see above).

    Warning

    You must not call synchronous methods from the main thread. The methods will assert if you do so.

    Note

    The synchronous methods can throw; you have to catch and handle the error.

    Parallel transactions

    While it is possible to create parallel transactions, there is little interest in doing so, since each committed transaction results in an index rebuild. Multiplying transactions therefore only degrades performance.

    Also, transactions are serially executed in the order they were committed, the latest transaction potentially overwriting the previous transactions’ result.

    Manual build

    As an alternative to using write transactions, OfflineIndex also offers a manual build feature. Provided that you have:

    • the index settings (one JSON file); and
    • the objects (as many JSON files as needed, each containing an array of objects)

    … available as local files on disk, you can replace the index’s content with that data by calling build(...).

    Caveats

    Limitations

    Though offline indices support most features of an online index, there are some limitations:

    • Objects must contain an objectID field. The SDK will refuse to index objects without an ID.

    • Partial updates are not supported.

    • Replica indices are not supported.

    Differences

    • Settings are not incremental: the new settings completely replace the previous ones. If a setting is omitted in the new version, it reverts back to its default value. (This is in contrast with the online API, where you can only specify the settings you want to change and omit the others.)

    • You cannot batch arbitrary write operations in a single method call (as you would do with Index.batch(...)). However, all write operations are de facto batches, since they must be wrapped inside a transaction (see below).

    See more

    Declaration

    Swift

    @objcMembers
    public class OfflineIndex : NSObject, Searchable